/**
 * @author Aaron
 * @createTime 10:40 2022/6/1
 **/
package db_main

import (
	"errors"
	"fmt"
	"longmen/server/config/global"
	utils2 "longmen/server/pkg/common/helper/util"
	"longmen/server/pkg/db/mysql"
	"longmen/server/pkg/db/mysql/models/models_main"
	"time"

	"longmen/server/pkg/common/api_models"

	"gorm.io/gorm"
)

func GetNobleDescById(id uint8) (*api_models.NobleNew, error) {
	o := &api_models.NobleNew{}
	err := global.GetR().Model(&models_main.NobleNew{}).
		Where("id=?", id).
		Take(&o).
		Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		err = nil
	}
	if err != nil {
		err = fmt.Errorf("%s%s", utils2.Convert2(), err.Error())
	}

	utils2.Json2Struct(o.Barrage, &o.BarrageDetail)
	utils2.Json2Struct(o.Trumpet, &o.TrumpetDetail)
	global.GetR().Model(&models_main.Props{}).Where("id=?", o.PropsID).Find(&o.MountDetail)
	return o, nil
}

func GetNobleNameList() ([]*api_models.GetNobleListResp, error) {
	o := make([]*api_models.GetNobleListResp, 0)
	err := mysql.GetRTable(&models_main.NobleNew{}).
		Order("weight DESC").
		Find(&o).
		Error
	if err != nil {
		err = fmt.Errorf("%s%s", utils2.Convert2(), err.Error())
	}

	for idx, v := range o {
		utils2.Json2Struct(v.Barrage, &o[idx].BarrageDetail)
		utils2.Json2Struct(v.Trumpet, &o[idx].TrumpetDetail)
		global.GetR().Model(&models_main.Props{}).Where("id=?", v.PropsID).First(&o[idx].MountDetail)
	}
	return o, nil
}

func GetNoblePriceList() ([]*api_models.GetNoblePriceList, error) {
	o := make([]*api_models.GetNoblePriceList, 0)
	err := mysql.GetRTable(&models_main.Noble{}).
		Select("id,price,renew_price").
		Order("weight DESC").
		Find(&o).
		Error
	if err != nil {
		err = fmt.Errorf("%s%s", utils2.Convert2(), err.Error())
	}
	return o, nil
}

func GetNobleById(id uint8) (*models_main.NobleNew, error) {
	o := &models_main.NobleNew{}
	err := mysql.GetRTable(&models_main.NobleNew{}).
		Where("id = ?", id).
		Find(o).
		Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		err = nil
	}
	if err != nil {
		err = fmt.Errorf("%s%s", utils2.Convert2(), err.Error())
	}
	return o, nil
}

func GetNobleByPropsId(propsId uint8) (*models_main.NobleNew, error) {
	o := &models_main.NobleNew{}
	err := mysql.GetRTable(&models_main.NobleNew{}).
		Where("props_id = ?", propsId).
		Find(o).
		Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		err = nil
	}
	if err != nil {
		err = fmt.Errorf("%s%s", utils2.Convert2(), err.Error())
	}
	return o, nil
}

func GetNobleRewardById(id uint8) (*api_models.NobleReward, error) {
	o := new(api_models.NobleReward)
	err := global.GetR().
		Raw("SELECT np.reward AS reward,"+
			"np.renew_reward  "+
			"AS renew_reward FROM "+
			"db_noble n LEFT JOIN db_noble_promo np "+
			"ON  n.rank_id =np.noble_id WHERE n.rank_id = ?", id).
		Take(o).
		Error
	if err != nil {
		err = fmt.Errorf("%s%s", utils2.Convert2(), err.Error())
	}
	return o, nil
}

func GetPropListByNobleId(id uint8) ([]*api_models.GetPropByNobleId, error) {
	o := make([]*api_models.GetPropByNobleId, 0)
	err := mysql.GetRTable(&models_main.NobleProp{}).
		Find(&o, "noble_id", id).
		Error
	if err != nil {
		err = fmt.Errorf("%s%s", utils2.Convert2(), err.Error())
	}
	return o, nil
}

func GetNobleRecordByUid(uid int) (*api_models.NobleRecordRes, error) {
	resp := &api_models.NobleRecordRes{}
	return resp, nil
	err := global.GetR().Raw(
		"SELECT db_noble_record.*,db_noble_new.`name`,db_noble_new.`gift_discount`,db_noble_new.id as rank_id "+
			"FROM db_noble_record LEFT JOIN db_noble_new "+
			"ON db_noble_new.id=db_noble_record.noble_id "+
			"WHERE db_noble_record.uid=? AND db_noble_record.expiration > ? "+
			"ORDER BY db_noble_record.id DESC limit 1", uid, time.Now().Unix()).Scan(resp).Error
	return resp, err
}

func GetNobleRecordByUidAndNobleID(uid int, nobleID int) (*api_models.NobleRecordRes, error) {
	resp := &api_models.NobleRecordRes{}
	err := global.GetR().Raw(
		"SELECT db_noble_record.*,db_noble_new.`name`,db_noble_new.`gift_discount`,db_noble_new.id as rank_id "+
			"FROM db_noble_record LEFT JOIN db_noble_new "+
			"ON db_noble_new.id=db_noble_record.noble_id "+
			"WHERE db_noble_record.uid=? AND db_noble_record.expiration > ? and db_noble_record.noble_id=? "+
			"ORDER BY db_noble_record.id DESC limit 1", uid, time.Now().Unix(), nobleID).Scan(resp).Error
	return resp, err
}

func GetNobleList() ([]*models_main.NobleNew, error) {
	o := make([]*models_main.NobleNew, 0)
	err := mysql.GetRTable(&models_main.NobleNew{}).
		Select(" * ").
		Order("weight DESC").
		Find(&o).
		Error
	if err != nil {
		err = fmt.Errorf("%s %s", utils2.Convert2(), err.Error())
	}
	return o, nil
}

/**
 * @Author willi
 * @Description //TODO
 * @Date 15:34 2022/9/8
 * @Param
 * @return
 **/
func GetProps(uid uint64) *models_main.PropsItem {
	var o *models_main.PropsItem
	global.GetR().Raw("select product_name,eff_time,exp_time,icon,t2.id,t2.`type`,noble_id from db_user_backpack_statistics t1,db_props_new t2 where t1.uid=? and t1.type=102 and t1.gid=t2.id and t1.eff_time <= unix_timestamp( now()) AND t1.exp_time >= unix_timestamp( now()) and selected=1 order by t2.weight desc limit 1 ", uid).Find(&o)
	return o
}

// 用户使用中的座骑
func GetNobleInUse(uid uint64) *api_models.NobleRecordRes {
	propsItem := GetProps(uid)
	resp := &api_models.NobleRecordRes{}
	if propsItem == nil {
		resp, _ = GetNobleRecordByUid(int(uid))
	} else {
		resp.Name = propsItem.ProductName
		resp.RankId = uint8(propsItem.NobleId)
		resp.Id = uint(propsItem.Id)
		resp.NobleId = uint8(propsItem.NobleId)
		resp.Expiration = propsItem.ExpTime
		noble, _ := GetNobleByPropsId(uint8(resp.Id))
		if noble.Id > 0 {
			resp.GiftDiscount = int(noble.GiftDiscount)
			// if 100-noble.GiftDiscount > 0 {
			// 	resp.GiftDiscount = 100 - int(noble.GiftDiscount)
			// }
		}
	}
	return resp
}

func GetNoblePrivilege(nobleId uint8) (*models_main.NoblePrivilege, error) {
	var o *models_main.NoblePrivilege
	err := mysql.GetRTable(&models_main.NoblePrivilege{}).
		Where("noble_id=?", nobleId).
		First(&o).
		Error
	if err != nil {
		err = fmt.Errorf("%s %s", utils2.Convert2(), err.Error())
	}
	return o, nil
}

/**
 * @Author willi
 * @Description //使道具选中
 * @Date 15:34 2022/9/8
 * @Param
 * @return
 **/
func UseBackPackProps(uid int64, propsId, propsType int32) int64 {
	session := global.GetX().Begin()
	if err := session.Exec("update db_user_backpack_statistics set selected=2 where uid=? and type=?", uid, propsType).Error; err != nil {
		session.Rollback()
		return 0
	}
	if session.Exec("update db_user_backpack_statistics set selected=1 where uid=? and gid=? and type=? and eff_time <= unix_timestamp( now()) AND exp_time >= unix_timestamp( now()) and selected<>1 ", uid, propsId, propsType).RowsAffected == 0 {
		session.Rollback()
		return 0
	}
	if err := session.Commit().Error; err != nil {
		session.Rollback()
		return 0
	}
	return 1
}

func GetNobleExistsRecordByUid(uid int) (*api_models.NobleRecordRes, error) {
	resp := &api_models.NobleRecordRes{}
	err := global.GetR().Raw(
		"SELECT db_noble_record.*,db_noble_new.`name`,db_noble_new.`gift_discount`,db_noble_new.id as rank_id "+
			"FROM db_noble_record LEFT JOIN db_noble_new "+
			"ON db_noble_new.id=db_noble_record.noble_id "+
			"WHERE db_noble_record.uid=? "+
			"ORDER BY db_noble_record.id DESC limit 1", uid).Scan(resp).Error
	return resp, err
}
